//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.quickserver.util.pool.thread;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
import org.apache.commons.pool.ObjectPool;
import org.quickserver.net.server.ClientHandler;
import org.quickserver.util.pool.QSObjectPool;
import org.quickserver.util.xmlreader.PoolConfig;

public class ClientPool {
    private static final Logger logger = Logger.getLogger(ClientPool.class.getName());
    protected List clients = new ArrayList(3);
    protected ObjectPool pool;
    protected PoolConfig poolConfig;
    private int countNioWriteThreads;
    private int maxThreadsForNioWrite = 10;

    public ClientPool(QSObjectPool objectPool, PoolConfig poolConfig) {
        this.poolConfig = poolConfig;
        this.pool = objectPool;
    }

    public ObjectPool getObjectPool() {
        return this.pool;
    }

    public void addClient(Runnable r) throws NoSuchElementException {
        this.addClient(r, false);
    }

    public synchronized void addClient(Runnable r, boolean keepObjOnFail) throws NoSuchElementException {
        this.clients.add(r);
        ClientThread ct = null;

        try {
            ct = (ClientThread)this.pool.borrowObject();
            if (!ct.isReady()) {
                this.wait(500L);
            } else {
                synchronized(ct) {
                    ct.notify();
                }
            }
        } catch (NoSuchElementException var9) {
            logger.info("No free threads: " + var9);
            if (!keepObjOnFail) {
                this.clients.remove(r);
            }

            throw var9;
        } catch (Exception var10) {
            logger.warning("Error in addClient: " + var10 + ", Closing client: " + (ClientHandler)r);

            try {
                ((ClientHandler)r).forceClose();
            } catch (Exception var7) {
                logger.warning("Error closing client: " + var7);
            }

            try {
                if (ct != null) {
                    this.pool.returnObject(ct);
                }
            } catch (Exception var6) {
                logger.warning("Error in returning thread: " + var6);
            }
        }

    }

    public synchronized void returnObject(Object object) {
        try {
            this.pool.returnObject(object);
        } catch (Exception var3) {
            logger.warning("IGONRED: Error while returning object : " + var3);
            ((Thread)object).interrupt();
        }

    }

    public synchronized Runnable getClient() {
        return this.clients.isEmpty() ? null : (Runnable)this.clients.remove(0);
    }

    public boolean isClientAvailable() {
        return !this.clients.isEmpty();
    }

    public void close() throws Exception {
        this.pool.close();
    }

    public void clear() throws Exception {
        this.pool.clear();
    }

    public int getNumActive() {
        return this.pool.getNumActive();
    }

    public int getNumIdle() {
        return this.pool.getNumIdle();
    }

    public final Iterator getAllClientThread() {
        return ((QSObjectPool)this.pool).getAllActiveObjects();
    }

    public Object getObjectToSynchronize() {
        return ((QSObjectPool)this.pool).getObjectToSynchronize();
    }

    public PoolConfig getPoolConfig() {
        return this.poolConfig;
    }

    public void setMaxThreadsForNioWrite(int count) {
        this.maxThreadsForNioWrite = count;
    }

    public int getMaxThreadsForNioWrite() {
        return this.maxThreadsForNioWrite;
    }

    protected void nioWriteEnd() {
        --this.countNioWriteThreads;
        if (this.countNioWriteThreads < 0) {
            logger.warning("countNioWriteThreads should not go less than 0");
            this.countNioWriteThreads = 0;
        }

    }

    protected void nioWriteStart() {
        ++this.countNioWriteThreads;
    }

    public boolean shouldNioWriteHappen() {
        return this.maxThreadsForNioWrite <= 0 || this.countNioWriteThreads < this.maxThreadsForNioWrite;
    }
}
